#include "MainWindow.hpp"
#include <spdlog/spdlog.h>
#include <fmt/format.h>
#include <fstream>
#include <spdlog/spdlog.h>
#include <unistd.h>

extern char **environ;

MainWindow::MainWindow()
: m_VBox(Gtk::Orientation::VERTICAL)
, btnCreateProject("新建项目")
, btnCreateTask("新建任务")
, btnShotControl("开始拍摄")
, createTaskDlg(this)
{
  {
    std::ifstream configFile("./config");
    if(!configFile.is_open())
      throw std::runtime_error("无法打开配置文件");
    std::string url;
    configFile>>url;
    projectClient.reset(new ProjectClient(url));
    serverControl.reset(new ServerControl(url));
    wsClient.reset(new WebsocketClinet(url,"/Terminal/Connect"));
  }

  set_title("HBTY Project Manager");
  set_default_size(300, 350);

  m_VBox.set_margin(5);
  set_child(m_VBox);

  // Add the ColumnView, inside a ScrolledWindow, with the button underneath:
  m_ScrolledWindow.set_child(projectView);

  // Only show the scrollbars when they are necessary:
  m_ScrolledWindow.set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC);
  m_ScrolledWindow.set_expand();

  m_VBox.append(m_ScrolledWindow);
  m_VBox.append(m_ButtonGrid);

  m_ButtonGrid.set_margin(5);
  btnCreateProject.set_hexpand();
  btnCreateTask.set_hexpand();
  btnShotControl.set_hexpand();
  m_ButtonGrid.attach(btnCreateProject,0,0);
  m_ButtonGrid.attach(btnCreateTask,1,0);
  m_ButtonGrid.attach(btnShotControl,0,1);
  btnCreateProject.signal_clicked().connect(sigc::mem_fun(*this,&MainWindow::on_btnCreateProject_click));
  btnCreateTask.signal_clicked().connect(sigc::mem_fun(*this,&MainWindow::on_btnCreateTask_click));
  btnShotControl.signal_clicked().connect(sigc::mem_fun(*this,&MainWindow::on_btnShotControl));

  createProjectDlg.set_default_size(200,100);
  createProjectDlg.set_transient_for(*this);
  createProjectDlg.set_modal();
  createProjectDlg.set_hide_on_close();
  createProjectDlg.signal_hide().connect(sigc::mem_fun(*this,&MainWindow::on_createProjectDlg_hidden));
  createTaskDlg.signal_result_connect(sigc::mem_fun(*this,&MainWindow::on_createTaskDlg_hidden));

  dlgMsg=Gtk::AlertDialog::create();
  dlgMsg->set_buttons({"OK"});
  dlgMsg->set_cancel_button(0);

  m_refTreeModel=Gtk::TreeStore::create(m_columns);
  projectView.set_model(m_refTreeModel);

  projectView.append_column("名称",m_columns.m_col_name);
  projectView.append_column("信息",m_columns.m_col_info);

  projectView.signal_row_activated().connect(sigc::mem_fun(*this,&MainWindow::on_projectView_row_activated));

  UpdateProjectView();
}

MainWindow::~MainWindow()
{
}

void MainWindow::on_btnCreateProject_click()
{
  createProjectDlg.set_visible(true);
}


void MainWindow::on_btnCreateTask_click()
{
  createTaskDlg.Show();
}

void MainWindow::on_createProjectDlg_hidden()
{
  if(createProjectDlg.GetSucessStatus())
  {
    if(projectClient->CreateProject(createProjectDlg.GetProjectName(),createProjectDlg.GetDescribe()))
    {
      UpdateProjectView();
    }
    else
    {
      dlgMsg->set_message("无法创建项目");
      dlgMsg->show(*this);
    }
  }
}

void MainWindow::on_projectView_row_activated(const Gtk::TreeModel::Path& path,Gtk::TreeViewColumn* column)
{
  const auto iter=m_refTreeModel->get_iter(path);
  if(iter)
  {
    const auto row=*iter;

  }
}

void MainWindow::UpdateProjectView()
{
  m_refTreeModel->clear();
  const auto projectList=projectClient->ProjectList();
  for(const std::string & i : projectList)
  {
    auto project_row=*(m_refTreeModel->append());
    project_row[m_columns.col_level]=0;
    project_row[m_columns.m_col_name]=i;
    project_row[m_columns.m_col_info]="Project";
    
    const auto taskList=projectClient->TaskList(i);
    for(const std::string & j : taskList)
    {
      auto task_row=*(m_refTreeModel->append(project_row.children()));
      task_row[m_columns.col_level]=1;
      task_row[m_columns.m_col_name]=j;
      task_row[m_columns.m_col_info]="Task";
    }
  }
}

void MainWindow::on_createTaskDlg_hidden()
{
  if(createTaskDlg.GetSuccessStatus())
  {
    auto refTreeSelection=projectView.get_selection();
    auto iter=refTreeSelection->get_selected();
    if(iter)
    {
      auto row=*iter;
      std::string projectName;
      if(row[m_columns.col_level]==0)
      {
        Glib::ustring parent_name=row[m_columns.m_col_name];
        projectName=parent_name;
      }
      else
      {
        Gtk::TreeIter<Gtk::TreeRow> projectNode=iter;
        for(;projectNode->parent() && (*projectNode)[m_columns.col_level]!=0;projectNode=projectNode->parent())
          ;
        projectName=(Glib::ustring)(*projectNode)[m_columns.m_col_name];
      }
      if(projectClient->CreateTask(projectName,createTaskDlg.GetTaskName()))
        UpdateProjectView();
      else
      {
        dlgMsg->set_message("无法创建任务");
        dlgMsg->show(*this);
      }
    }
  }
}

void MainWindow::on_btnShotControl()
{
  if(serverControl->GetRecordStatus())
  {
    serverControl->StopRecord();
    btnShotControl.set_label("开始录像");
  }
  else
  {
    auto refTreeSelection=projectView.get_selection();
    auto iter=refTreeSelection->get_selected();
    if(iter && (*iter)[m_columns.col_level]==1)
    {
        std::string TaskName=(Glib::ustring)(*iter)[m_columns.m_col_name];
        iter=iter->parent();
        std::string ProjectName=(Glib::ustring)(*iter)[m_columns.m_col_name];
        serverControl->StartRecord(ProjectName,TaskName);
        btnShotControl.set_label("停止录像");
    }
  }
}


//废弃
void MainWindow::on_btnOpenRealtime_click()
{
  auto refTreeSelection=projectView.get_selection();
  auto iter=refTreeSelection->get_selected();
  if(iter)
  {
    if((*iter)[m_columns.col_level]==1)
    {
      std::string TaskName=(Glib::ustring)(*iter)[m_columns.m_col_name];
      iter=iter->parent();
      std::string ProjectName=(Glib::ustring)(*iter)[m_columns.m_col_name];
      std::string task_arg=fmt::format("--task={}",TaskName);
      std::string project_arg=fmt::format("--project={}",ProjectName);

      pid_t pid=fork();
      if(pid==0)
      {
        char filename[]="RealtimeUI";
        char* argv[4];
        argv[0]=filename;
        argv[1]=(char*)malloc(task_arg.size()+1);
        memcpy(argv[1],task_arg.c_str(),task_arg.size()+1);
        argv[2]=(char*)malloc(project_arg.size()+1);
        memcpy(argv[2],project_arg.c_str(),project_arg.size()+1);
        argv[3]=nullptr;

        execve("RealtimeUI",argv,environ);
        spdlog::error("无法启动RealtimeUI");
        exit(-1);
      }
      else if(pid==-1)
      {
        dlgMsg->set_message("fork调用错误");
        dlgMsg->show(*this);
      }
      else
      {
      }
    }
  }
}
